<template>
  <div class="container">
    <div class="app-container">
      <el-button type="primary" size="small" style="margin-bottom: 15px" @click="showAddDialog"
        >添加角色</el-button
      >
      <!-- 表格 -->
      <el-table
        :data="roles"
        style="width: 100%"
        :border="true"
        :row-style="{ height: '64px' }"
        :header-cell-style="{ background: '#f5f6f8' }"
      >
        <el-table-column label="序号" type="index" width="50px"></el-table-column>
        <el-table-column prop="name" label="角色" width="180">
          <template slot-scope="{ row }">
            <!-- 条件判断 -->
            <el-input v-model="row.editRow.name" v-if="row.isEdit" size="mini"></el-input>
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="state" label="启用" width="180">
          <!-- 自定义列 -->
          <template v-slot="{ row }">
            <el-switch
              v-if="row.isEdit"
              v-model="row.editRow.state"
              :active-value="1"
              :inactive-value="0"
            ></el-switch>
            <span v-else>{{ row.state === 1 ? '已启用' : row.state === 0 ? '未启用' : '无' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="描述">
          <template slot-scope="{ row }">
            <!-- 编辑状态 -->
            <el-input
              v-if="row.isEdit"
              v-model="row.editRow.description"
              type="textarea"
              size="mini"
            ></el-input>
            <!-- 非编辑状态 -->
            <span v-else>{{ row.description }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <!-- 编辑状态 -->
            <div v-if="scope.row.isEdit">
              <el-button type="primary" size="mini" @click="confirmEdit(scope.row)"
                >确 定</el-button
              >
              <el-button size="mini" @click="cancelEdit(scope.row)">取 消</el-button>
            </div>
            <!-- 非编辑状态 -->
            <div v-else>
              <el-link type="primary" :underline="false" @click="btnPermission(scope.row.id)"
                >分配权限</el-link
              >
              <el-link
                type="primary"
                :underline="false"
                style="margin: 0 10px"
                @click="btnEditRow(scope.row)"
                >编辑</el-link
              >
              <!-- 注意这里官方文档 点击确认事件是 @confirm ,实际是 @onconfirm -->
              <el-popconfirm title="确定删除该条数据吗？" @onConfirm="deleteRole(scope.row.id)">
                <el-link slot="reference" type="primary" :underline="false">删除</el-link>
              </el-popconfirm>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页条 -->
      <!-- 
        .sync 是 Vue 提供的一种 语法糖，用于简化 父子组件之间的双向数据绑定。
      它相当于(以currentPage 为例)：
            <el-pagination
              :current-page="currentPage"
             @update:current-page="val => currentPage = val"
            />

       如果不用 .sync，需要手动监听事件：
          <el-pagination
            :current-page="currentPage"
            @current-change="handleCurrentChange"
          />
          ...
          handleCurrentChange(val) {
            this.currentPage = val;
          }
       -->
      <el-pagination
        class="pagination-style"
        layout="sizes,prev, pager, next"
        :total="total"
        :page-sizes="[5, 10, 15, 20]"
        :page-size.sync="pageInfo.pagesize"
        :current-page.sync="pageInfo.page"
        @current-change="handleCurrentChange"
        @size-change="handleSizeChange"
      >
      </el-pagination>
      <!-- 对话框 -->
      <el-dialog
        title="添加角色"
        :visible.sync="dialogVisible"
        width="33%"
        @close="$refs.roleForm.resetFields()"
      >
        <el-form ref="roleForm" label-width="120px" :model="roleModel" :rules="roleRules">
          <el-form-item label="角色名称" prop="name">
            <el-input v-model="roleModel.name" size="mini" style="width: 300px"></el-input>
          </el-form-item>
          <el-form-item label="启用">
            <el-switch v-model="roleModel.state" :active-value="1" :inactive-value="0"></el-switch>
          </el-form-item>
          <el-form-item label="角色描述" prop="description">
            <el-input
              v-model="roleModel.description"
              type="textarea"
              style="width: 300px"
              :rows="3"
              size="mini"
            ></el-input>
          </el-form-item>
          <el-form-item>
            <el-row type="flex" justify="center">
              <el-col :span="12">
                <el-button type="primary" @click="addRole" size="mini">确 定</el-button>
                <el-button
                  @click="
                    dialogVisible = false
                    $refs.roleForm.resetFields()
                  "
                  size="mini"
                  >取 消</el-button
                ></el-col
              >
            </el-row></el-form-item
          >
        </el-form>
      </el-dialog>
      <!-- 放置权限弹层 -->
      <el-dialog title="分配权限" :visible.sync="showPermissionDialog" width="50%">
        <!-- 放置权限数据（树形） -->
        <el-tree
          ref="permTree"
          node-key="id"
          :data="permissionData"
          show-checkbox
          default-expand-all
          :props="{ label: 'name' }"
          :default-checked-keys="permIds"
          check-strictly
        >
        </el-tree>
        <div slot="footer" style="display: flex; justify-content: center">
          <el-button type="primary" @click="assignPermisssion" size="mini">确 定</el-button>
          <el-button @click="showPermissionDialog = false" size="mini">取 消</el-button>
        </div>
      </el-dialog>
    </div>
  </div>
</template>
<script>
import {
  getRoleListByPageService,
  addRoleService,
  deleteRoleService,
  updateRoleService,
  getRoleDetailService,
  assignPermissionService
} from '@/api/role'
import { getPermissionListService } from '@/api/permission.js'
import { transListToTreeData } from '@/utils/index'
export default {
  name: 'Role',
  created() {
    this.getRoles()
  },
  data() {
    return {
      roles: [],
      total: 0,
      pageInfo: {
        page: 1,
        pagesize: 5
      },
      //显示添加角色对话框
      dialogVisible: false,
      roleModel: {
        name: '',
        description: '',
        state: 0
      },
      roleRules: {
        name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
        description: [{ required: true, message: '角色描述不能为空', trigger: 'blur' }]
      },
      showPermissionDialog: false, // 控制权限弹层
      currentId: null,
      permissionData: [], // 权限列表树形数据
      permIds: []
    }
  },
  methods: {
    async getRoles() {
      const res = await getRoleListByPageService(this.pageInfo)
      this.roles = res.data.rows
      this.total = res.data.total
      //针对每一行添加一个编辑标记
      this.roles.forEach((item) => {
        // item.isEdit = false; //添加一个属性 初始值为 false
        //数据响应式的问题  数据变化 视图更新
        //添加的动态属性  不具备响应式特点
        //this.$set(目标对象,属性名称,初始值) 可以针对目标对象添加属性 响应式
        this.$set(item, 'isEdit', false)
        //添加缓存
        this.$set(item, 'editRow', {
          name: item.name,
          state: item.state,
          description: item.description
        })
      })
    },
    handleCurrentChange(val) {
      this.getRoles()
    },
    handleSizeChange(val) {
      this.getRoles()
    },
    showAddDialog() {
      this.dialogVisible = true
    },
    //添加新角色
    addRole() {
      this.$refs.roleForm.validate(async (valid) => {
        if (valid) {
          const { data } = await addRoleService(this.roleModel)
          this.$message.success('新增角色成功')
          //重新获取角色列表
          this.getRoles()
          this.dialogVisible = false
        }
      })
    },
    //删除角色
    async deleteRole(id) {
      await deleteRoleService(id)
      this.$message.success('删除角色成功')
      //删除的如果是最后一个,要让页码 -1 再去更新数据 ,并且当前页必须 大于1 才能让页码 -1
      if (this.roles.length === 1 && this.pageInfo.page > 1) {
        this.pageInfo.page--
      }
      this.getRoles()
    },
    //显示编辑表单
    btnEditRow(row) {
      row.isEdit = true
      //更新缓存数据
      row.editRow = {
        name: row.name,
        state: row.state,
        description: row.description
      }
    },
    //取消编辑
    cancelEdit(row) {
      row.isEdit = false
    },
    //确定编辑
    async confirmEdit(row) {
      //检查必填项(由于这里表格里面用不了 el-form 标签,所以我们要手动校验)
      if (row.editRow.name && row.editRow.description) {
        //下一步操作
        await updateRoleService({ ...row.editRow, id: row.id })
        //更新成功
        // this.getRoles(); // 如果这么写就不能支持多行同时编辑，且发请求会增大服务器压力
        // row.name = row.editRow.name; // eslint的校验 误判
        // Object.assign(target,source)   将一个或者多个源对象中所有可枚举的自有属性复制到目标对象，并返回修改后的目标对象。
        Object.assign(row, {
          ...row.editRow,
          isEdit: false // 退出编辑模式
        }) // 规避eslint的误判

        this.$message.success('更新角色成功')
        row.isEdit = false
      } else {
        this.$message.warning('角色名称和角色描述不能为空')
      }
    },
    // 点击分配权限后触发
    async btnPermission(id) {
      this.currentId = id
      const { data } = await getRoleDetailService(id)
      this.permIds = data.permIds
      const { data: permList } = await getPermissionListService()
      this.permissionData = transListToTreeData(permList, 0)
      this.showPermissionDialog = true
    },
    // 分配权限
    async assignPermisssion() {
      await assignPermissionService({
        id: this.currentId,
        permIds: this.$refs.permTree.getCheckedKeys()
      })
      console.log(this.$refs.permTree.getCheckedKeys())
      this.$message.success('分配权限成功')
      this.showPermissionDialog = false
    }
  }
}
</script>
<style lang="scss" scoped>
.app-container {
  padding: 20px 20px 50px;
  .pagination-style {
    margin-top: 35px;
    text-align: center;
  }
}
</style>
